/**
 * 
 */
package service;


import util.JankExecutors;

import java.util.concurrent.ExecutorService;

/**
 * https://blog.csdn.net/xiaokang123456kao/article/details/77331878
 * 三条线程循环交替打印ABC
 * 
 * @author jiangnk001
 *
 */
public class MultiThreadPrintABC {
	
	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		Object a = new Object();
		Object b = new Object();
		Object c = new Object();
		
		PrintCharacter printA = new PrintCharacter("A", c, a);
		PrintCharacter printB = new PrintCharacter("B", a, b);
		PrintCharacter printC = new PrintCharacter("C ", b, c);
		
		ExecutorService executorPool = JankExecutors.newFixedSizeExecutorPool(3, "print");
		executorPool.submit(printA);
		Thread.sleep(5);
		executorPool.submit(printB);
		Thread.sleep(5);
		executorPool.submit(printC);
	}
}

class PrintCharacter implements Runnable{
	
	private String cha;
	private final Object pre;
	private final Object self;
	
	private int count = 0;
	
	public PrintCharacter(String ch, Object p, Object s){
		this.cha = ch;
		this.pre = p;
		this.self = s;
	}
	
	@Override
	public void run(){
		while (count < 10) {
			/*
			  同时获得两个锁才能打印，因为总共三个线程，所以可以保证同时只有一个线程能打印
			 */
			synchronized (pre) {
				synchronized (self) {
					System.out.print(cha);
					count++;
					// 唤醒其他竞争self锁的线程，但是当前线程要等到 synchronized (self)块执行完才结束
					self.notify();
				}
				try {
					// 让出当前线程，此时pre和self锁都释放了
					pre.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}	
}


